package store

import (
	"encoding/json"
	"git.oschina.net/YPTArch/usercenter/oauth2/models"
	"git.oschina.net/YPTArch/usercenter/libs/redis"
	"fmt"
	"git.oschina.net/YPTArch/usercenter/config"
	"git.oschina.net/YPTArch/basic/sys/logs"
)



var server TokenStore
func init() {
	logs.Logger.Info("初始化存储")
	server=newRedisTokenStore()
}
func GetStoreServer() (*TokenStore) {
	return &server
}

type TokenStore struct {
	*redis.RedisServer
}

func newRedisTokenStore() (store TokenStore) {
	 c:= redis.NewRedis(config.GetRedisAddress(),config.GetRedisPwd())
	 c.Do("SELECT",config.GetRedisDBIndex())
	 redis:=TokenStore{c}
	return redis
}

// Create create and store the new token information
func (ts *TokenStore) Create(info models.TokenInfo) (err error) {
	jv, err := json.Marshal(info)
	if err != nil {
		return
	}
	val:=string(jv)
	var key=""
	if key=info.GetUserID();key!=""{
		key="User:"+key
		ts.Set(key,val)
		ts.SetExpire(key,72000)
	}
	if key=info.GetAccess();key!=""{
		key="AccessToken:"+key
		ts.Set(key,val)
		ts.SetExpire(key,info.GetAccessExpiresIn().Nanoseconds())
	}
	if key=info.GetCode();key!=""{
		key="Code:"+key
		ts.Set(key,val)
		ts.SetExpire(key,info.GetCodeExpiresIn().Nanoseconds())
	}
	if key=info.GetRefresh();key!=""{
		key="RefreshToekn:"+key
		ts.Set(key,val)
		ts.SetExpire(key,info.GetRefreshExpiresIn().Nanoseconds())
	}
	return
}

// remove key
func (ts *TokenStore) remove(key string) (error) {
	_,err := ts.RedisServer.DelData(key)
	if err!=nil {
		return err
	}
	return nil
}

// RemoveByCode use the authorization code to delete the token information
func (ts *TokenStore) RemoveByCode(code string) (err error) {
	err = ts.remove("Code:"+code)
	return
}

// RemoveByAccess use the access token to delete the token information
func (ts *TokenStore) RemoveByAccess(access string) (err error) {
	err = ts.remove("AccessToken:"+access)
	return
}

// RemoveByRefresh use the refresh token to delete the token information
func (ts *TokenStore) RemoveByRefresh(refresh string) (err error) {
	err = ts.remove("RefreshToekn:"+refresh)
	return
}

func (ts *TokenStore) getData(key string) (ti models.TokenInfo, err error) {
	data,err := ts.GetBytes(key)
	if err!=nil{
		return nil,err
	}
	var t=new(models.Token)
	err= json.Unmarshal(data,&t)
	if err!=nil{
		fmt.Println(err)
		return nil,err
	}
	ti=t
	return ti,nil
}
// GetByCode use the authorization code for token information data
func (ts *TokenStore) GetByCode(code string) (ti models.TokenInfo, err error) {
	ti, err = ts.getData("Code:"+code)
	if err !=nil{
		return nil,err
	}
	ts.RemoveByCode(code)
	return
}

// GetByAccess use the access token for token information data
func (ts *TokenStore) GetByAccess(access string) (ti models.TokenInfo, err error) {
	ti, err = ts.getData("AccessToken:"+access)
	return ti,err
}

// GetByRefresh use the refresh token for token information data
func (ts *TokenStore) GetByRefresh(refresh string) (ti models.TokenInfo, err error) {
	ti, err = ts.getData("RefreshToekn:"+refresh)
	return
}